# base_enums.py
from __future__ import annotations

from enum import Enum
from typing import Set, List


# ---------------------------------------------------------------------------
# 基类：所有业务枚举的公共能力
# ---------------------------------------------------------------------------
class BaseDBEnum(Enum):
	"""数据库持久化枚举基类"""

	# ----------- 通用能力 -----------
	def label(self) -> str:
		"""返回中文标签"""
		return self._label_map()[self.value]

	@classmethod
	def values(cls) -> Set[str]:
		"""返回所有枚举值的集合，方便白名单校验"""
		return {item.value for item in cls}

	@classmethod
	def db_values(cls) -> List[str]:
		"""返回有序列表，用于 SQL IN 查询等需要顺序的场景"""
		return [item.value for item in cls]

	@classmethod
	def _label_map(cls) -> dict[str, str]:
		"""子类必须实现，返回 {value: 中文标签}"""
		raise NotImplementedError


# ---------------------------------------------------------------------------
# 设备枚举
# ---------------------------------------------------------------------------
class DeviceType(BaseDBEnum):
	STATION = "STATION"
	BOX = "BOX"
	RTU = "RTU"
	METER = "METER"

	@classmethod
	def _label_map(cls) -> dict[str, str]:
		return {
			"STATION": "台区",
			"BOX": "电箱",
			"RTU": "采集器",
			"METER": "电表",
		}


class DeviceStatus(BaseDBEnum):
	REGISTERED = "REGISTERED"
	ONLINE = "ONLINE"
	OFFLINE = "OFFLINE"
	ABNORMAL = "ABNORMAL"
	DECOMMISSIONED = "DECOMMISSIONED"
	NORMAL = "NORMAL"
	FAULT = "FAULT"

	@classmethod
	def _label_map(cls) -> dict[str, str]:
		return {
			"REGISTERED": "已登记",
			"ONLINE": "在线",
			"OFFLINE": "离线",
			"ABNORMAL": "异常",
			"DECOMMISSIONED": "已报废",
			"NORMAL": "正常",
			"FAULT": "故障",
		}


# 电表类型枚举
class MeterType(BaseDBEnum):
	THREE_PHASE = "THREE_PHASE"
	SINGLE = "SINGLE"

	@classmethod
	def _label_map(cls) -> dict[str, str]:
		return {
			"THREE_PHASE": "三相表",
			"SINGLE": "单相表"
		}


# 相别枚举
class MeterPhase(BaseDBEnum):
	A = "A"
	B = "B"
	C = "C"

	@classmethod
	def _label_map(cls) -> dict[str, str]:
		return {
			"A": "A相表",
			"B": "B相表",
			"C": "C相表",
		}


# 上行类型
class UpLinkType(BaseDBEnum):
	Two = "2G"
	Four = "4G"
	NB = "NB"
	ETH = "ETH"

	@classmethod
	def _label_map(cls) -> dict[str, str]:
		return {
			"2G": "2G",
			"4G": "4G",
			"NB": "NB-IoT",
			"ETH": "Ethernet",
		}


# ----------- 告警枚举 -----------
class AlarmAction(BaseDBEnum):
	ACK = "ACK"
	RECOVER = "RECOVER"
	CLOSE = "CLOSE"

	@classmethod
	def _label_map(cls) -> dict[str, str]:
		return {
			"ACK": "人工确认",
			"RECOVER": "工单恢复",
			"CLOSE": "强制关闭",
		}


# ---------------- 告警工单规则枚举----------------
class AlarmType(BaseDBEnum):
	OVER_CURRENT = "OVER_CURRENT"
	LOW_VOLTAGE = "LOW_VOLTAGE"
	COMM_LOST = "COMM_LOST"
	OVER_VOLTAGE = "OVER_VOLTAGE"
	PHASE_BREAK = "PHASE_BREAK"
	TAMPER = "TAMPER"
	THREE_TAMPER = "THREE-TAMPER"  # 三相电表非法开箱
	SINGLE_TAMPER = "SINGLE-TAMPER"  # 单相电表非法开箱
	OVER_POWER = "OVER_POWER"
	OVER_ENERGY = "OVER_ENERGY"
	TEMP_OVER = "TEMP_OVER"  # 新增温度过高告警
	HIGH_TEMP = "HIGH_TEMP"  # 兼容旧的温度告警
	OVER_LOAD = "OVER_LOAD"  # 过载告警
	UNDER_VOLTAGE = "UNDER_VOLTAGE"  # 欠电压（兼容）
	CURRENT_OVER = "CURRENT_OVER"  # 电流过大（兼容）
	VOLTAGE_OVER = "VOLTAGE_OVER"  # 电压过高（兼容）
	POWER_OVER = "POWER_OVER"  # 功率过高（兼容）
	UNKNOWN_ALARM = "UNKNOWN_ALARM"  # 无匹配规则
	FIELD_MISSING = "FIELD_MISSING"  # 字段值缺失
	NORMAL = "NORMAL"  # 规则均通过，不告警

	@classmethod
	def _label_map(cls):
		return {
			"OVER_CURRENT": "过电流",
			"LOW_VOLTAGE": "欠电压",
			"COMM_LOST": "通信中断",
			"OVER_VOLTAGE": "过电压",
			"PHASE_BREAK": "断相",
			"TAMPER": "非法开箱",
			"THREE-TAMPER": "非法开箱",  # 三相电表非法开箱
			"SINGLE-TAMPER": "非法开箱",  # 单相电表非法开箱
			"OVER_POWER": "功率过高",
			"OVER_ENERGY": "电量异常",
			"TEMP_OVER": "温度过高",
			"HIGH_TEMP": "高温告警",
			"OVER_LOAD": "过载",
			"UNDER_VOLTAGE": "欠电压",
			"CURRENT_OVER": "电流过大",
			"VOLTAGE_OVER": "电压过高",
			"POWER_OVER": "功率过高",
			"UNKNOWN_ALARM": "未知告警",
			"FIELD_MISSING": "字段缺失",
			"NORMAL": "正常",
		}


class AlarmStatus(BaseDBEnum):
	OPEN = "OPEN"
	ACKED = "ACKED"
	CLOSED = "CLOSED"
	RECOVERED = "RECOVERED"

	@classmethod
	def _label_map(cls):
		return {
			"OPEN": "待处理",
			"ACKED": "已确认",
			"CLOSED": "已关闭",
			"RECOVERED": "自动恢复",
		}


class AlarmCloseReason(BaseDBEnum):
	WORK_ORDER_CLOSED = "WORK_ORDER_CLOSED"
	NORMAL = "NORMAL"
	FALSE_POSITIVE = "FALSE_POSITIVE"
	DEVICE_REPLACE = "DEVICE_REPLACE"

	@classmethod
	def _label_map(cls):
		return {
			"NORMAL": "正常恢复",
			"FALSE_POSITIVE": "误报",
			"DEVICE_REPLACE": "设备更换",
		}


# ---------------- 告警规则严重性（用于 am_alarm_rule）----------------
class AlarmRuleSeverity(BaseDBEnum):
	HINT = 1
	GENERAL = 2
	SEVERITY = 3

	@classmethod
	def _label_map(cls) -> dict[int, str]:
		return {
			1: "提示",
			2: "一般",
			3: "严重",
		}


class WorkOrderStatus(BaseDBEnum):
	CREATED = "CREATED"
	DISPATCHED = "DISPATCHED"
	DONE = "DONE"
	CLOSED = "CLOSED"
	PROCESSING = "PROCESSING"
	RESOLVED = "RESOLVED"
	VERIFIED = "VERIFIED"
	AUTO_CLOSED = "AUTO_CLOSED"

	@classmethod
	def _label_map(cls):
		return {
			"CREATED": "已创建",
			"DISPATCHED": "已派单",
			"DONE": "已完成",
			"CLOSED": "已关闭",
			"PROCESSING": "处理中",
			"RESOLVED": "已解决",
			"VERIFIED": "已验证",
			"AUTO_CLOSED": "系统自动关闭",
		}


# ---------------- 工单优先级 ----------------
class WorkOrderPriority(BaseDBEnum):
	LOW = "LOW"
	MEDIUM = "MEDIUM"
	HIGH = "HIGH"
	URGENT = "URGENT"

	@classmethod
	def _label_map(cls):
		return {
			"LOW": "低",
			"MEDIUM": "中",
			"HIGH": "高",
			"URGENT": "紧急",
		}


# ---------------- 工单来源类型 ----------------
class WorkOrderSourceType(BaseDBEnum):
	ALARM = "ALARM"
	MANUAL = "MANUAL"

	@classmethod
	def _label_map(cls):
		return {
			"ALARM": "告警",
			"MANUAL": "手工创建",
		}


# ---------------- 工单设备类型 ----------------
class WorkOrderDeviceType(BaseDBEnum):
	STATION = "STATION"
	BOX = "BOX"
	RTU = "RTU"
	METER = "METER"

	@classmethod
	def _label_map(cls):
		return {
			"STATION": "台区",
			"BOX": "电箱",
			"RTU": "采集器",
			"METER": "电表",
		}


# ---------------- 工单操作类型 ----------------
class WorkOrderAction(BaseDBEnum):
	CREATE = "CREATE"
	DISPATCH = "DISPATCH"
	PROCESS = "PROCESS"
	RESOLVE = "RESOLVE"
	CLOSE = "CLOSE"
	REJECT = "REJECT"

	@classmethod
	def _label_map(cls):
		return {
			"CREATE": "创建",
			"DISPATCH": "分派",
			"PROCESS": "处理",
			"RESOLVE": "解决",
			"CLOSE": "关闭",
			"REJECT": "拒绝",
		}


# ---------------- 事件类型 ----------------
class EventType(BaseDBEnum):
	"""领域事件类型枚举"""
	ALARM_RAISED = "ALARM_RAISED"
	ALARM_RECOVERED = "ALARM_RECOVERED"
	WORK_ORDER_CLOSED = "WORK_ORDER_CLOSED"

	@classmethod
	def _label_map(cls):
		return {
			"ALARM_RAISED": "告警产生",
			"ALARM_RECOVERED": "告警恢复",
			"WORK_ORDER_CLOSED": "工单关闭",
		}
